﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
using namespace std;


class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
	virtual void BuyTicket() { cout << "买票-打折" << endl; }
};
class Soldier : public Person {
public:
	virtual void BuyTicket() { cout << "买票-优先" << endl; }
};
void Func(Person* ptr)
{
	// 这⾥可以看到虽然都是Person指针Ptr在调⽤BuyTicket 
	// 但是跟ptr没关系，⽽是由ptr指向的对象决定的。 
	ptr->BuyTicket();
}
int main()
{
	// 其次多态不仅仅发⽣在派⽣类对象之间，多个派⽣类继承基类，重写虚函数后 
	// 多态也会发⽣在多个派⽣类之间。 
	Person ps;
	Student st;
	Soldier sr;
	Func(&ps);
	Func(&st);
	Func(&sr);
	return 0;
}


//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//protected:
//	int _b = 1;
//	char _ch = 'x';
//};
//int main()
//{
//	Base b;
//	cout << sizeof(b) << endl;
//	return 0;
//}


//class Car
//{
//public:
//	virtual void Drive() = 0;
//};
//class Benz :public Car
//{
//public:
//	virtual void Drive()
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//class BMW :public Car
//{
//public:
//	virtual void Drive()
//	{
//		cout << "BMW-操控" << endl;
//	}
//};
//int main()
//{
//	// 编译报错：error C2259: “Car”: ⽆法实例化抽象类 
//	Car car;
//	Car* pBenz = new Benz;
//	pBenz->Drive();
//	Car* pBMW = new BMW;
//	pBMW->Drive();
//	return 0;
//}




//class A
//{
//public:
//	 virtual ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//class B : public A {
//public:
//	~B()
//	{
//		cout << "~B()->delete:" << _p << endl;
//		delete _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//// 只有派⽣类Student的析构函数重写了Person的析构函数，下⾯的delete对象调⽤析构函数，才能
////构成多态，才能保证p1和p2指向的对象正确的调⽤析构函数。
//int main()
//{
//	A* p1 = new A;
//	A* p2 = new B;
//	delete p1;
//	delete p2;
//	return 0;
//}

//class A {};
//class B : public A {};
//class Person {
//public:
//	virtual A* BuyTicket()
//	{
//		cout << "买票-全价" << endl;
//		return nullptr;
//	}
//};
//class Student : public Person {
//public:
//	virtual B* BuyTicket()
//	{
//		cout << "买票-打折" << endl;
//		return nullptr;
//	}
//};
//void Func(Person* ptr)
//{
//	ptr->BuyTicket();
//}
//int main()
//{
//	Person ps;
//	Student st;
//	Func(&ps);
//	Func(&st);
//	return 0;
//}


//class A
//{
//public:
//	virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
//	virtual void test() { func(); }
//};
//
//class B : public A
//{
//public:
//	virtual void func(int val = 0) { std::cout << "B->" << val << std::endl; }
//};
//
//int main(int argc, char* argv[])
//{
//	B* p = new B;
//	p->test();
//	return 0;
//}


//class Person
//{
//public:
//	virtual void BuyTicket() { cout << "全价" << endl; }
//};
//class Student : public Person
//{
//public:
//	virtual void BuyTicket() { cout << "半价" << endl; }
//};
//
//void Func(Person& ptr)
//{
//	ptr.BuyTicket();
//}
//
//int main()
//{
//	Person a1;
//	Student a2;
//	//a1.BuyTicket();
//	//a2.BuyTicket();
//	Func(a1);
//	Func(a2);
//	return 0;
//}

//class Person
//{
//public:
//	string _name; // 姓名 
//	/*int _tel;
//int _age;
// string _gender;
// string _address;*/
// // ...
//};
//// 使⽤虚继承Person类 
//class Student : virtual public Person
//{
//protected:
//	int _num; //学号 
//};
//// 使⽤虚继承Person类 
//class Teacher : virtual public Person
//{
//protected:
//	int _id; // 职⼯编号 
//};
//// 教授助理 
//class Assistant : public Student, public Teacher
//{
//protected:
//	string _majorCourse; // 主修课程 
//};
//int main()
//{
//	// 使⽤虚继承，可以解决数据冗余和⼆义性 
//	Assistant a;
//	a._name = "peter";
//	return 0;
//}


//class Person
//{
//public:
//	string _name;
//	static int _count;
//};
//int Person::_count = 0;
//class Student : public Person
//{
//protected:
//	int _stuNum;
//};
//int main()
//{
//	Person p;
//	Student s;
//	// 这⾥的运⾏结果可以看到⾮静态成员_name的地址是不⼀样的 
//	// 说明派⽣类继承下来了，⽗派⽣类对象各有⼀份 
//	cout << &p._name << endl;
//	cout << &s._name << endl;
//	// 这⾥的运⾏结果可以看到静态成员_count的地址是⼀样的 
//	// 说明派⽣类和基类共⽤同⼀份静态成员 
//	cout << &p._count << endl;
//	cout << &s._count << endl;
//	// 公有的情况下，⽗派⽣类指定类域都可以访问静态成员 
//	cout << Person::_count << endl;
//	cout << Student::_count << endl;
//	return 0;
//}


//class Student;
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name; // 姓名 
//};
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号 
//};
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	cout << s._stuNum << endl;
//}
//int main()
//{
//	Person p;
//	Student s;
//	// 编译报错：error C2248: “Student::_stuNum”: ⽆法访问 protected 成员 
//	// 解决⽅案：Display也变成Student 的友元即可 
//	Display(p, s);
//
//	return 0;
//}


//class Person
//{
//public:
//	Person(const char* name = "peter")
//		: _name(name)
//	{
//		cout << "Person()" << endl;
//	}
//
//	Person(const Person& p)
//		: _name(p._name)
//	{
//		cout << "Person(const Person& p)" << endl;
//	}
//
//	Person& operator=(const Person& p)
//	{
//		cout << "Person operator=(const Person& p)" << endl;
//		if (this != &p)
//			_name = p._name;
//
//		return *this;
//	}
//
//	~Person()
//	{
//		cout << "~Person()" << endl;
//	}
//protected:
//	string _name; // 姓名 
//};
//class Student : public Person
//{
//public:
//	Student(const char* name, int num ,const string& address)
//		: Person(name)
//		, _num(num)
//		, _address(address)
//	{
//		cout << "Student()" << endl;
//	}
//
//	Student(const Student& s)
//		: Person(s)
//		, _num(s._num)
//	{
//		cout << "Student(const Student& s)" << endl;
//	}
//
//	Student& operator = (const Student& s)
//	{
//		cout << "Student& operator= (const Student& s)" << endl;
//		if (this != &s)
//		{
//			// 构成隐藏，所以需要显⽰调⽤ 
//			Person::operator =(s);
//			_num = s._num;
//		}
//		return *this;
//	}
//
//	~Student()
//	{
//		cout << "~Student()" << endl;
//	}
//protected:
//	int _num;//学号
//	string _address;
//};
//int main()
//{
//	Student s1("jack", 18 ,"nb");
//	Student s2(s1);
//	Student s3("rose", 17,"shi");
//	s1 = s3;
//
//	return 0;
//}




//namespace bit
//{
//	template<class T>
//	class stack : public std::vector<T>
//	{
//	public:
//		void push(const T& x)
//		{
//			// 基类是类模板时，需要指定⼀下类域， 
//			// 否则编译报错:error C3861: “push_back”: 找不到标识符 
//			// 因为stack<int>实例化时，也实例化vector<int>了 
//			// 但是模版是按需实例化，push_back等成员函数未实例化，所以找不到 
//			vector<T>::push_back(x);
//			//push_back(x);
//		}
//		void pop()
//		{
//			vector<T>::pop_back();
//		}
//		const T& top()
//		{
//			return vector<T>::back();
//		}
//		bool empty()
//		{
//			return vector<T>::empty();
//		}
//	};
//}
//int main()
//{
//	bit::stack<int> st;
//	st.push(1);
//	st.push(2);
//	st.push(3);
//	while (!st.empty())
//	{
//		cout << st.top() << " ";
//		st.pop();
//	}
//	return 0;
//}



//class Person
//{
//public:
//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
//	void identity()
//	{
//		cout << "void identity()" << _name << endl;
//	}
//protected:
//	string _name = "张三"; // 姓名 
//	string _address; // 地址 
//	string _tel; // 电话 
//	int _age = 18; // 年龄 
//};
//class Student : public Person
//{
//public:
//	// 学习 
//	void study()
//	{
//		cout << Person::_name << endl;
//	}
//protected:
//	int _stuid;// 学号
//	string _name = "李四";
//};
//class Teacher : public Person
//{
//public:
//	// 授课 
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string title; // 职称 
//	string _name = "王五";
//
//};
//int main()
//{
//	Student s;
//	Teacher t;
//	s.identity();
//	t.identity();
//	return 0;
//}

//class Student
//{
//public:
//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
//	void identity()
//	{
//		// ...
//	}
//	// 学习 
//	void study()
//	{
//		// ...
//	}
//protected:
//	string _name = "peter"; // 姓名 
//	string _address; // 地址 
//	string _tel; // 电话 
//	int _age = 18; // 年龄 
//	int _stuid; // 学号 
//};
//class Teacher
//{
//public:
//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
//	void identity()
//	{
//		// ...
//	}
//	// 授课 
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string _name = "张三"; // 姓名 
//	int _age = 18; // 年龄 
//	string _address; // 地址 
//	string _tel; // 电话 
//	string _title; // 职称 
//};
//int main()
//{
//	return 0;
//}


//int main()
//{  
//	string s = "hello world";
//	string::iterator it1 = s.begin() + 1;
//	string::iterator it2 = s.end() - 1;
//	string s1(it1, it2);
//
//	return 0;
//}

//class A
//{
//public:
//	A(int a1)
//		:_a1(a1)
//	{}
//
//	A(int a1, int a2)
//		:_a1(a1)
//		, _a2(a2)
//	{}
//	void Print()
//	{
//		cout << _a1 << " " << _a2 << endl;
//	}
//	int Get() const
//	{
//		return _a1 + _a2;
//	}
//private:
//	int _a1 = 1;
//	int _a2 = 2;
//};
//class B
//{
//public:
//	B(const A& a)
//		:_b(a.Get())
//	{}
//private:
//	int _b = 0;
//};
//int main()
//{
//	A aa1 = 1;
//	aa1.Print();
//	const A& aa2 = 1;
//	A aa3 = { 2,2 };
//	B b = aa3;
//	const B& rb = aa3;
//	return 0;
//}